import { _decorator, Color, color, Component, director, EventTouch, Game, Label, Node, Sprite, UIOpacity, UITransform, v3, Vec2 } from 'cc';
import { BoardMgr } from './BoardMgr';
import { GameMgr } from './GameMgr';
import { UIMgr } from './UIMgr';
import { UserData } from '../Data/UserData';
import { Guide } from '../game/Guide';
import ServiceAPI from '../src/api/service.api';
import { Popup } from '../src/ui/page/popup';
import { AudioMgr } from './AudioMgr';
import { Url } from '../Tools/Url';
import Tools from '../Tools/Tools';
const { ccclass, property } = _decorator;

@ccclass('TouchMgr')
export class TouchMgr extends Component {
    /** 单例模式 */
    private static _ins: TouchMgr;
    constructor() {
        super();
        TouchMgr._ins = this;
    }
    public static get ins(): TouchMgr {
        if (!this._ins) {
            this._ins = new TouchMgr();
        }
        return TouchMgr._ins;
    }

    /** UITransform 缓存 */
    private uiTransform!: UITransform;
    // 记录下标数组
    private selectedIndexes: number[][] = [];
    // 记录word节点数组
    private selectedNodes: Node[] = [];
    // 记录word节点锁下标
    private seletedNodeLock: number[][] = []
    // 锁定的方向
    private lockedDirection: number[] | null = null;
    // 记录初始触摸位置
    private initialTouchPos: Vec2 = new Vec2();
    private distance: number = 0;


    private touchLock: boolean = false;

    onLoad() {
        this.uiTransform = this.node.getComponent(UITransform)!;

        // 添加触摸事件
        this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
    }

    start() {
        GameMgr.ins.startTimer();
    }

    // 触摸开始
    private onTouchStart(event: EventTouch) {
        // if (this.touchLock) {
        //     return
        // }
        // 触摸开始时，重置定时器
        GameMgr.ins.resetTimer();
        this.selectedIndexes = [];
        this.selectedNodes = [];
        this.seletedNodeLock = [];
        this.lockedDirection = null;
        this.initialTouchPos = event.getUILocation();
        this.checkTouchPosition(this.initialTouchPos);
        BoardMgr.ins.drawCircleToWord('Start', this.selectedIndexes);
        UIMgr.ins.condContainer.getComponent(Sprite).color = new Color().fromHEX(BoardMgr.ins.wordColorStr);
        // UIMgr.ins.updateCondLabel('', BoardMgr.ins.wordColorStr);
    }

    // 触摸移动
    private onTouchMove(event: EventTouch) {
        // if (this.touchLock) {
        //     return
        // }
        const currentTouchPos = event.getUILocation();
        this.distance = Vec2.distance(this.initialTouchPos, currentTouchPos);
        if (this.distance <= 100) {
            this.lockedDirection = null;
        }
        if (!this.lockedDirection && this.distance > 100) {
            this.lockedDirection = this.calculateDirection(this.initialTouchPos, currentTouchPos);
        }
        // console.log(this.lockedDirection);
        // if (this.lockedDirection ) {
        this.checkTouchPosition(currentTouchPos);
        // }
    }

    // 触摸结束
    private async onTouchEnd(event: EventTouch) {
        // if (this.touchLock) {
        //     return void 0;
        // }
        // 启动定时器，记录 5 秒
        GameMgr.ins.startTimer();

        let isCorrect = this.validateWord();
        if (isCorrect) {
            // this.touchLock = true;
            try {
                AudioMgr.ins.playOneShot(Url.AUDIO.SFX5, 1);
                BoardMgr.ins.drawLineTimes++;
                UIMgr.ins.closeCondContainer();
                for (let i = 0; i < this.seletedNodeLock.length; i++) {
                    const element = this.seletedNodeLock[i];
                    BoardMgr.ins.wordNodeLockArr[element[0]][element[1]] = false;
                }
                // for (let i = 0; i < this.selectedNodes.length; i++) {
                //     const element = this.selectedNodes[i];
                //     element.getChildByName('lbl_word').getComponent(Label).color = Color.WHITE;
                // }
                UIMgr.ins.createWordEffect(this.selectedNodes, this.selectedIndexes);


                let location = event.getUILocation();
                const localPos = this.uiTransform.convertToNodeSpaceAR(v3(location.x, location.y, 0));
                if (!UserData.data.isCommer) {
                    // console.log('发起消除奖励---请求', start_date.toLocaleString());
                    if (BoardMgr.ins.drawLineTimes >= BoardMgr.ins.correctAnswerText.length) {
                        GameMgr.ins.getElimitateCash(localPos, true);
                    } else {
                        GameMgr.ins.getElimitateCash(localPos);
                    }
                }

                if (UserData.data.isCommer && BoardMgr.ins.drawLineTimes < 4) {
                    Guide.ins.completeCurGuide(BoardMgr.ins.drawLineTimes + 1)
                }

                //  判断是否过关
                if (BoardMgr.ins.drawLineTimes >= BoardMgr.ins.correctAnswerText.length) {
                    GameMgr.ins.isPassLevel = true;
                    GameMgr.ins.resetTimer();
                    //  过关弹窗
                    if (UserData.data.isCommer) {
                        UIMgr.ins.createConsecutiveEffect(v3(0, 0, 0), BoardMgr.ins.drawLineTimes);

                        //  引导时走新人奖励弹窗
                        Tools.delay(0.5, () => Guide.ins.completeCurGuide(5));
                    } else {
                        UIMgr.ins.createConsecutiveEffect(v3(0, 0, 0), BoardMgr.ins.drawLineTimes);
                        //  走正常过关奖励弹窗
                        let config = await this.retryPassLevelConfig(UserData.data.userId);
                        console.log(config);
                        if (!config) {
                            Tools.delay(0.5, () => GameMgr.ins.passLevel());
                        } else {
                            Tools.delay(0.5, () => Popup.Passlevelpage(config));
                        }

                    }
                    for (let i = 0; i < BoardMgr.ins.correctAnswerText.length; i++) {
                        UIMgr.ins.answerNodeContainer.children[i].getComponent(UIOpacity).opacity = 100;
                    }

                }
            } catch (e) {
                // this.touchLock = false;
                console.warn('look at debug!!!', e);
            }

            // Tools.delay(0.5, () => this.touchLock = false);
        } else {
            // for (let i = 0; i < this.selectedNodes.length; i++) {
            //     const element = this.selectedNodes[i];
            //     element.getChildByName('lbl_word').getComponent(Label).color = Color.BLACK;
            // }
            AudioMgr.ins.playOneShot(Url.AUDIO.SFX4, 1);
            BoardMgr.ins.drawCircleToWord('End', this.selectedIndexes);
            BoardMgr.ins.clearLineAndAndReduction(this.selectedNodes, 0);
            UIMgr.ins.updateCondLabel('', BoardMgr.ins.wordColorStr);
            UIMgr.ins.condContainerShake();
        }

        BoardMgr.ins.applyColorToNodesBasedOnLockStatus();

    }

    private __passlevel_config_cache__: ReturnType<typeof ServiceAPI.PassLevelConfig>;
    async retryPassLevelConfig(userId: number, retries: number = 3) {
        let attempt = 0;
        let config = null;
        while (attempt < retries) {
            try {
                config = await ServiceAPI.PassLevelConfig(userId);

                if (config?.cashAmount !== undefined) {
                    this.__passlevel_config_cache__ = config
                    return config;
                } else {
                    this.__passlevel_config_cache__ = config;
                    console.warn("PassLevelConfig 返回空值或 cashTotal 未定义");
                }
            } catch (error) {
                console.error(`PassLevelConfig 请求失败 (第 ${attempt + 1} 次):`, error);
            }
            attempt++;
            // 等待一段时间后重试（可以根据需求增加延迟）
            await new Promise(resolve => setTimeout(resolve, 1000)); // 延迟 1 秒
        }
        // if (!this.__passlevel_config_cache__) {
        //     let con = {
        //         cashAmount: Tools.randFloat(0.5, 1)
        //     }
        //     return con;
        // }
        return this.__passlevel_config_cache__;
    }


    /**计算触摸位置对应的下标*/
    private checkTouchPosition(location: Vec2) {
        const boardWidth = 800;
        const boardHeight = 800;
        const wordWidth = boardWidth / BoardMgr.ins.wordNodeArr[0].length;
        const wordHeight = boardHeight / BoardMgr.ins.wordNodeArr.length;

        // 将屏幕坐标转换为棋盘节点的局部坐标
        const localPos = this.uiTransform.convertToNodeSpaceAR(v3(location.x, location.y, 0));

        // 计算对应的下标
        const col = Math.floor((localPos.x + boardWidth / 2) / wordWidth);
        const row = Math.floor((boardHeight / 2 - localPos.y) / wordHeight);

        if (this.isValidIndex(row, col) && !this.isAlreadySelected(row, col)) {
            // 只允许在锁定方向上移动
            if (this.isInLockedDirection(row, col)) {
                this.selectedIndexes.push([row, col]);
                this.selectedNodes.push(BoardMgr.ins.wordNodeArr[row][col]);
                this.seletedNodeLock.push([row, col]);
                for (let i = 0; i < this.selectedNodes.length; i++) {
                    const element = this.selectedNodes[i];
                    element.getChildByName('lbl_word').getComponent(Label).color = Color.WHITE;
                }
                switch (this.selectedNodes.length) {
                    case 1:
                        AudioMgr.ins.playOneShot(Url.AUDIO.SFX111, 1);
                        break;
                    case 2:
                        AudioMgr.ins.playOneShot(Url.AUDIO.SFX222, 1);
                        break;
                    case 3:
                        AudioMgr.ins.playOneShot(Url.AUDIO.SFX333, 1);
                        break;
                    case 4:
                        AudioMgr.ins.playOneShot(Url.AUDIO.SFX444, 1);
                        break;
                    case 5:
                        AudioMgr.ins.playOneShot(Url.AUDIO.SFX555, 1);
                        break;
                    case 6:
                        AudioMgr.ins.playOneShot(Url.AUDIO.SFX666, 1);
                        break;

                    default:
                        break;
                }
            }
        }
        BoardMgr.ins.drawLineToWord(this.selectedIndexes);
        BoardMgr.ins.showCondWord(this.selectedIndexes, BoardMgr.ins.wordColorStr);
    }

    /** 判断下标是否有效*/
    private isValidIndex(row: number, col: number): boolean {
        // 先检查行和列是否在有效范围内
        if (row >= 0 && row < BoardMgr.ins.wordNodeArr.length && col >= 0 && col < BoardMgr.ins.wordNodeArr[0].length) {
            // 再判断 wordNodeLockArr[row][col] 是否为 true
            return BoardMgr.ins.wordNodeLockArr[row][col] === true;
        }
        // 如果行列不在有效范围内，直接返回 false
        return false;
    }

    // 判断下标是否已被记录
    private isAlreadySelected(row: number, col: number): boolean {
        // 查找当前下标是否已被记录
        const indexPosition = this.selectedIndexes.findIndex(index => index[0] === row && index[1] === col);

        if (indexPosition !== -1) {
            // 如果是最后一个已记录的下标，返回 true
            if (indexPosition === this.selectedIndexes.length - 1) {
                return true;
            } else {
                // 如果不是最后一个，删除这个记录的下标后面的所有数据
                this.selectedIndexes.splice(indexPosition + 1);
                for (let i = indexPosition + 1; i < this.selectedNodes.length; i++) {
                    this.selectedNodes[i].getChildByName('lbl_word').getComponent(Label).color = Color.BLACK;
                }
                this.selectedNodes.splice(indexPosition + 1);
                this.seletedNodeLock.splice(indexPosition + 1);

                return true;
            }
        }

        // 如果没有被记录，返回 false
        return false;
    }


    // 判断是否在锁定方向上移动
    private isInLockedDirection(row: number, col: number): boolean {
        if (!this.lockedDirection || this.selectedIndexes.length === 0) {
            return true;
        }
        const [lastRow, lastCol] = this.selectedIndexes[this.selectedIndexes.length - 1];
        const [dirRow, dirCol] = this.lockedDirection;


        return (row - lastRow === dirRow) && (col - lastCol === dirCol);
    }

    /**计算移动方向*/
    private calculateDirection(startPos: Vec2, endPos: Vec2): [number, number] {
        const angle = Math.atan2(endPos.y - startPos.y, endPos.x - startPos.x);
        const directions: { [key: string]: [number, number] } = {
            '0': [0, 1],
            '45': [-1, 1],
            '90': [-1, 0],
            '135': [-1, -1],
            '180': [0, -1],
            '-135': [1, -1],
            '-90': [1, 0],
            '-45': [1, 1],
            '-180': [0, -1],
        };

        const roundedAngle = Math.round(angle * (180 / Math.PI) / 45) * 45;
        // console.log(roundedAngle);

        return directions[roundedAngle.toString()];
    }



    /** 验证所选字母是否组成了正确的单词 */
    private validateWord() {

        // 遍历 selectedIndexes，检查 selectedNodeLock 中的对应位置是否为 false
        const hasLockedNode = this.selectedIndexes.some(([i, j]) => BoardMgr.ins.wordNodeLockArr[i][j] === false);

        // 如果有位置被锁定，直接返回 false
        if (hasLockedNode) {
            console.log('有锁定的节点，验证失败！');
            return false;
        }

        // 验证 selectedIndexes 是否与 correctAnswerIndexes 中的某个数组相等
        const isCorrect = BoardMgr.ins.correctAnswerIndexes.some(correctIndexes =>
            JSON.stringify(correctIndexes) === JSON.stringify(this.selectedIndexes)
        );

        if (isCorrect) {
            // 处理正确的单词选择
            // console.log('正确答案!');
        } else {
            // 处理错误的选择
            // console.log('错误答案！');
        }

        return isCorrect;
    }

}
